package guowei.guliproduct.product.service.impl;

import guowei.common.constant.ProductConstant;
import guowei.common.constant.ProductStatus;
import guowei.common.to.BoundsTo;
import guowei.common.to.SkusToCommon;
import guowei.common.to.es.EsModel;
import guowei.common.to.es.WareSkuIdStocks;
import guowei.common.utils.R;
import guowei.guliproduct.product.entity.*;
import guowei.guliproduct.product.feign.DiscountFeign;
import guowei.guliproduct.product.feign.EsProductSave;
import guowei.guliproduct.product.feign.StorageWareStock;
import guowei.guliproduct.product.service.*;
import guowei.guliproduct.product.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import guowei.common.utils.PageUtils;
import guowei.common.utils.Query;

import guowei.guliproduct.product.dao.SpuInfoDao;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("spuInfoService")
@Slf4j
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuImagesService spuImagesService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Autowired
    private SkuInfoService skuInfoService;

    @Autowired
    private SkuImagesService skuImagesService;

    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    private DiscountFeign discountFeign;

    @Autowired
    private AttrService attrService;

    @Autowired
    private SpuInfoDescService spuInfoDescService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private StorageWareStock storageWareStock;

    @Autowired
    private EsProductSave esProductSave;

    private String defaultImg;

    /**
     * //1、保存spu基本信息、 pms_spu_infd
     * //2、保存spu的描述图片 pms_spu_info_desc
     * //3、保存spu的图片集 pms_spu_images
     * //4、保存spu的规格参数; pms_product_attr_value
     * //4.5、保存spu的积分信息; gulimall_sms->sms_spu_bounds/
     * //5、保存当前spu对应的所有sku信息.;
     * //5.1)、 sku的基本信息;pms_sku_info
     * //5.2)、 sku的图片信息;pms_sku_images
     * //5.3) 、 sku的销售属性信息.:pms_sku_sale_attr_value
     * //5.4) 、sku的优惠、满减等信息; gulimall_sms-> sms_sku_ladder\ sms_sku_full_reduction\ sps
     * @param params
     * @return
     */

    /**
     * 保存发布商品后的保存信息
     * @param spuInfoVo
     */
    @Transactional
    @Override
    public void fabushangpin(SpuInfoVo spuInfoVo) {
        //1、保存spu基本信息、 pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(spuInfoVo,spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        this.save(spuInfoEntity);

        //2、保存spu的描述图片 pms_spu_info_desc
        List<String> list = spuInfoVo.getDecript();
        SpuInfoDescEntity spuInfoDesc = new SpuInfoDescEntity();
        spuInfoDesc.setSpuId(spuInfoEntity.getId());
        spuInfoDesc.setDecript(String.join(",",list));
        spuInfoDescService.save(spuInfoDesc);



        //3、保存spu的图片集 pms_spu_images
        List<String> images = spuInfoVo.getImages();
        spuImagesService.saveAllImages(spuInfoEntity.getId(),images);

        //4、保存spu的规格参数; pms_product_attr_value
        List<BaseAttrs> baseAttrs = spuInfoVo.getBaseAttrs();
        List<ProductAttrValueEntity> collect = baseAttrs.stream().map(baseAttrs1 -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            productAttrValueEntity.setSpuId(spuInfoEntity.getId());
            productAttrValueEntity.setAttrValue(baseAttrs1.getAttrValues());
            productAttrValueEntity.setQuickShow(baseAttrs1.getShowDesc());
            Long attrId = baseAttrs1.getAttrId();
            productAttrValueEntity.setAttrId(attrId);
            AttrEntity attr = attrService.getById(attrId);
            productAttrValueEntity.setAttrName(attr.getAttrName());
            productAttrValueEntity.setAttrSort(0);

            return productAttrValueEntity;
        }).collect(Collectors.toList());
        productAttrValueService.savaAllCol(collect);

        //5、保存当前spu对应的所有sku信息;
        //5.1)、 sku的基本信息;pms_sku_info

        List<Skus> skus = spuInfoVo.getSkus();
        List<SkuInfoEntity> collect1 = skus.stream().map(skus1 -> {
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtils.copyProperties(skus1, skuInfoEntity);
            skuInfoEntity.setSpuId(spuInfoEntity.getId());
            skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
            skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
            skuInfoEntity.setSaleCount(0L);
            skuInfoEntity.setSkuDesc(skus1.getDescar().toString());

            //得到默认图片
            List<Images> images1 = skus1.getImages();
            for (Images image2:images1) {
                if (image2.getDefaultImg() == 1){
                    defaultImg = image2.getImgUrl();
                    break;
                }
            }
            skuInfoEntity.setSkuDefaultImg(defaultImg);
            skuInfoService.save(skuInfoEntity);

            List<SkuImagesEntity> imagesEntityList = images1.stream().filter(image3->{
                if (!StringUtils.isEmpty(image3.getImgUrl())){
                    return true;
                }
                else {
                    return false;
                }
            }).map(images2 -> {
        //5.2)、 sku的图片信息;pms_sku_images
                SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                skuImagesEntity.setSkuId(skuInfoEntity.getSkuId());
                skuImagesEntity.setImgUrl(images2.getImgUrl());
                skuImagesEntity.setDefaultImg(images2.getDefaultImg());
                skuImagesEntity.setImgSort(0);

                return skuImagesEntity;
            }).collect(Collectors.toList());
            skuImagesService.saveBatch(imagesEntityList);

        //5.3) 、 sku的销售属性信息.:pms_sku_sale_attr_value
            List<Attr> attr = skus1.getAttr();
            List<SkuSaleAttrValueEntity> collect2 = attr.stream().map(attr1 -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                BeanUtils.copyProperties(attr1, skuSaleAttrValueEntity);
                skuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
                skuSaleAttrValueEntity.setAttrSort(0);
                return skuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveBatch(collect2);

        //5.4) 、sku的优惠、满减等信息; gulimall_sms-> sms_sku_ladder\
            // sms_sku_full_reduction\
            // sms_member_price
            SkusToCommon skus2 = new SkusToCommon();
            BeanUtils.copyProperties(skus1,skus2);
            skus2.setSkuId(skuInfoEntity.getSkuId());
            R r = discountFeign.saveLadder(skus2);

            R r2 = discountFeign.saveReduction(skus2);

            R r3 = discountFeign.saveMembers(skus2);

            return skuInfoEntity;
        }).collect(Collectors.toList());


        //4.5、保存spu的积分信息; gulimall_sms->sms_spu_bounds
        Bounds bounds = spuInfoVo.getBounds();
        BoundsTo boundsTo = new BoundsTo();
        BeanUtils.copyProperties(bounds,boundsTo);
        boundsTo.setSpuId(spuInfoEntity.getId());
        discountFeign.saveBounds(boundsTo);

    }

    /**
     * 按条件进行spu管理查询
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageByKeys(Map<String, Object> params) {
        String key = (String) params.get("key");
        String brandId = (String) params.get("brandId");
        String catalogId = (String) params.get("catalogId");
        String status = (String) params.get("status");
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(brandId) && !"0".equals(brandId)){
            wrapper.eq("brand_id",brandId);
        }
        if (!StringUtils.isEmpty(catalogId)){
            wrapper.eq("catalog_id",catalogId);
        }
        if (!StringUtils.isEmpty(status)){
            wrapper.eq("publish_status",status);
        }
        if (!StringUtils.isEmpty(key)){
            wrapper.and(one->{
                one.eq("id",key).or().like("spu_name",key).or().like("spu_description",key);
            });
        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * spu商品上架
     * 1.得到该spu信息，并将要上架的信息保存在EsModel to类中，并发送给es保存在product索引处
     * @param spuId
     */
    @Override
    public void listingSpu(Long spuId) {
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));

//全部查询，所有是否有库存信息
        List<Long> skuIds = skuInfoEntities.stream().map(skuskusku -> {
            Long skuId = skuskusku.getSkuId();
            return skuId;
        }).collect(Collectors.toList());
        List<WareSkuIdStocks> stocks = storageWareStock.getStocks(skuIds);
        log.info("这次的信息是{}",stocks);
//map集合 key是skuId,  value是stock
//        Map<Long, Long> map = stocks.stream().collect(Collectors.toMap(WareSkuIdStocks::getSkuId, item -> item.getStock()));
        HashMap<Long, Long> map = new HashMap<>();
        for (WareSkuIdStocks ws:stocks) {
            map.put(ws.getSkuId(), ws.getStock());
        };

        //TODO 4.得到所有可检索的规格属性信息
        List<ProductAttrValueEntity> lists = productAttrValueService.getBySpuId(spuId);
        List<EsModel.Attrs> collect1 = lists.stream().filter(pav -> {
            Long attrId = pav.getAttrId();
            AttrEntity attr = attrService.getById(attrId);
            if (attr.getSearchType() == 1) {
                return true;
            } else {
                return false;
            }
        }).map(pav2 -> {
            Long attrId = pav2.getAttrId();
            AttrEntity attr = attrService.getById(attrId);
            EsModel.Attrs attrs = new EsModel.Attrs();
//todo 事后返回来发现，attrValue未带，故导致es检索时没有该属性
            String attrName = attr.getAttrName();
            QueryWrapper<ProductAttrValueEntity> wrapper1 = new QueryWrapper<ProductAttrValueEntity>().eq("attr_name", attrName).eq("spu_id",spuId);
            ProductAttrValueEntity one = productAttrValueService.getOne(wrapper1);
            String attrValue = one.getAttrValue();
            attrs.setAttrValue(attrValue);
            BeanUtils.copyProperties(attr, attrs);

            return attrs;
        }).collect(Collectors.toList());

        List<EsModel> esModels = skuInfoEntities.stream().map(skusku -> {
            EsModel esModel = new EsModel();
            BeanUtils.copyProperties(skusku, esModel);
            esModel.setSkuPrice(skusku.getPrice());
            esModel.setSkuImg(skusku.getSkuDefaultImg());

            //TODO 1 发送远程调用，库存系统查询是否存在有库存  尽量一下子查完，不要一下只查一个
            Long stock = map.get(skusku.getSkuId());
            if (stock == null || stock == 0){
                esModel.setHasStock(false);
            }else {
                esModel.setHasStock(true);
            }

            //TODO 2 热度评分
            esModel.setHotScore(0L);

            //TODO 3. 查询品牌信息和分类的名字
            BrandEntity brand = brandService.getById(esModel.getBrandId());
            esModel.setBrandName(brand.getName());
            esModel.setBrandImg(brand.getLogo());

            CategoryEntity categoryEntity = categoryService.getById(esModel.getCatalogId());
            esModel.setCatalogName(categoryEntity.getName());

//赋值所有可检索的规格信息
            esModel.setAttrs(collect1);
            return esModel;
        }).collect(Collectors.toList());
        //TODO 5.调用es发送保存请求，保存这些esModel信息
        esProductSave.saveProducts(esModels);

        //TODO 6.商家完成后，修改状态从新建变为上架
        SpuInfoEntity spuInfo = this.getById(spuId);
        spuInfo.setPublishStatus(ProductStatus.PRODUCT_SALE.getStatus());
        this.updateById(spuInfo);
    }

    /**
     * 一定能查到  很具skuId查询spu信息
     * @param skuId
     * @return
     */
    @Override
    public SpuInfoEntity getSpuInfoBySkuId(Long skuId) {
        SkuInfoEntity one = skuInfoService.getOne(new QueryWrapper<SkuInfoEntity>().eq("sku_id", skuId));
        Long spuId = one.getSpuId();

        SpuInfoEntity spuInfoEntity = this.getById(spuId);
        return spuInfoEntity;
    }
}